package com.blockmeta.bbs.immodule.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import androidx.annotation.ColorInt;
import android.text.InputFilter;
import android.text.Spanned;
import android.util.AttributeSet;

import com.blockmeta.bbs.baselibrary.utils.DimentionsUtil;
import com.blockmeta.bbs.immodule.R;

import java.io.UnsupportedEncodingException;

/**
 * @author AirThor
 * @date 2019/2/19.
 * 限制输入长度的输入框
 * 在GBK编码下汉字占2字节，数字英文占1字节，从而实现长度限制规则 1个=2字母数字=1汉字
 */
public class LengthLimitEditText extends androidx.appcompat.widget.AppCompatEditText {
    /**
     * 最大输入长度
     */
    private int mMaxLength = 10;

    private Paint mLimitHintPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

    private @ColorInt int mLimitHintColor = Color.BLACK;

    private float mLimitTextSize = 15;

    private int mLimitTextGravity;
    /**
     * 是否展示输入长度提示 默认为true
     */
    private boolean isShowLength;

    private static final InputFilter INVALIDFILTER = new InputFilter() {
        @Override
        public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
            return null;
        }
    };

    public LengthLimitEditText(Context context) {
        super(context);
        initialize();
    }

    public LengthLimitEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
        TypedArray typedArray=context.obtainStyledAttributes(attrs, R.styleable.LengthLimitEditText);
        mMaxLength = typedArray.getInteger(R.styleable.LengthLimitEditText_limit_text_length,10);
        mLimitHintColor = typedArray.getColor(R.styleable.LengthLimitEditText_limit_text_color,Color.BLACK);
        mLimitTextSize = typedArray.getDimension(R.styleable.LengthLimitEditText_limit_text_size,15);
        mLimitTextGravity = typedArray.getInteger(R.styleable.LengthLimitEditText_limit_text_gravity, 0);
        isShowLength = typedArray.getBoolean(R.styleable.LengthLimitEditText_limit_text_show_length,true);
        typedArray.recycle();
        initialize();
    }

    private void initialize() {
        mLimitHintPaint.setColor(mLimitHintColor);
        mLimitHintPaint.setTextSize(mLimitTextSize);
        mLimitHintPaint.setTextAlign(Paint.Align.RIGHT);
        setFilters(new InputFilter[]{new SupperLengthFilter(mMaxLength)});
    }

    public void setShowLength(boolean show){
        isShowLength = show;
        invalidate();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (isShowLength) {
            drawLimitHint(canvas);
        }
    }

    private void drawLimitHint(Canvas canvas) {
        String hint = length()+"/"+mMaxLength;
        float x = getMeasuredWidth()- DimentionsUtil.dp2px(8);
        float y = (getMeasuredHeight()-getPaddingTop()-getPaddingBottom()-mLimitHintPaint.getFontMetrics().bottom+mLimitHintPaint.getFontMetrics().top)/2-mLimitHintPaint.getFontMetrics().top;
        if(mLimitTextGravity == 1){
            //右上
            y = getPaddingTop() + DimentionsUtil.dp2px(mLimitTextSize) + DimentionsUtil.dp2px(8);

        }else if(mLimitTextGravity == 2){
            //右下
            y = getScrollY() + getMeasuredHeight() - DimentionsUtil.dp2px(3);

        }else if(mLimitTextGravity == 3){
            y = (getMeasuredHeight() + getScrollY() + mLimitTextSize) / 2;

        }
        canvas.drawText(hint,x,y,mLimitHintPaint);
    }

    @Override
    public int length() {
        try {
            if (getText()==null){
                return 0;
            }
            return getText().toString().getBytes("GBK").length/2;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return 0;
        }
    }
    private static class SupperLengthFilter implements InputFilter {
        private int mMax;

        public SupperLengthFilter(int maxLength) {
            mMax = maxLength;
        }
        @Override
        public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
            int keep = 0;
            int sourceLength = end-start;
            try {
                sourceLength = source.toString().getBytes("GBK").length/2;

                int destByteLength = dest.toString().getBytes("GBK").length/2;
                int destVariationalLength = dend-dstart;
                keep = mMax - (destByteLength-destVariationalLength);
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            if (keep <= 0||(sourceLength>keep)) {
                return "";
            } else if (keep >= sourceLength) {
                return null;
            } else {
                keep += start;
                if (Character.isHighSurrogate(source.charAt(keep - 1))) {
                    --keep;
                    if (keep == start) {
                        return "";
                    }
                }
                return source.subSequence(start, keep);
            }
        }
    }
}
